<?php

namespace App\Http\Service;

use App\Http\Controllers\Admin\Traits\AdminTrait;
use Illuminate\Support\Facades\Validator;
use App\Models\Admin\Advertisments;
use Illuminate\Support\Facades\DB;
use App\Exceptions\CdjException;
use App\Exceptions\ApiException;

class AdvertismentService extends BaseService
{
    use AdminTrait;

    public $operateData;
    public $advertismentModel;
    public $action;

    public $token;

    public function __construct(Advertisments $advertismentModel)
    {
        parent::__construct();
        $this->advertismentModel = $advertismentModel;
    }

    /**
     * @param 广告列表
     * @param array $id
     * @return array
     * @throws CdjException
     */
    public function getList($params)
    {
        $list = Advertisments::list($params);

        foreach ($list['list'] as &$value) {
            $platform = $this->getDirectonaryDesc($value['platform']);
            $value['pos'] = $this->getDirectonaryDesc($value['platform'], $value['pos']);
            $value['platform'] = $platform;
            $value['pic'] = json_decode($value['pic'], true);
            $value['created_at'] = date('Y-m-d H:i:s', $value['created_at']);
            $value['updated_at'] = date('Y-m-d H:i:s', $value['updated_at']);
        }

        return $list;
    }

    /**
     * @param 获取字典描述
     */
    public function getDirectonaryDesc($platform, $pos = 0)
    {
        if (!$platform) {
            return '';
        }

        $list = self::$config['advertisment'];
        foreach ($list as  $value) {
            if ($platform != $value['val'])
                continue;

            if (!$pos)
                return $value['name'];

            foreach ($value['children'] as $item) {
                if ($pos != $item['val'])
                    continue;

                return $item['name'];
            }
        }

        return '';
    }

    /**
     * @param 广告详情
     * @param array $id
     * @return array
     * @throws CdjException
     */
    public function getDetail($params)
    {
        if (!isset($params['id']) && !$params['id']) {
            throw new CdjException('广告ID不能为空', 40001);
        }

        $info = Advertisments::where('id', $params['id'])->first();
        $info->pic = json_decode($info->pic, true);
        if (!$info)
            throw new CdjException('广告信息不存在', 40002);

        return $info;
    }

    /**
     * @desc 数据处理
     * @param array $params
     * @return array
     * @throws CdjException
     */
    public function handler($params)
    {
        $this->action = $params['action'] ?? 'forbidden';
        switch ($this->action) {
            case "add":
            case "update":
                // 校验,完善入库数据
                $this->checkFillData($params);
                // 入库数据
                $this->storageData();
                break;
            case "del":
                $info = Advertisments::where('id', $params['id'])->first();
                if (!$info)
                    throw new CdjException('广告信息不存在', 40002);
                Advertisments::find($params['id'])->delete();
                break;
            case "uptown":
                $validator = Validator::make($params, ['id' => 'required|numeric', 'status' => 'required|numeric',]);
                if ($validator->fails())
                    throw new CdjException($validator->errors()->first(), 40001);

                $info = Advertisments::where('id', $params['id'])->first();
                if (!$info)
                    throw new CdjException('广告信息不存在', 40002);
                Advertisments::where('id', $params['id'])->update(['status' => $params['status']]);
                break;
            default:
                throw new CdjException('非法操作', 50001);
        }

        return ['id' => $this->operateData['id'] ?? $params['id']];
    }

    private function checkFillData($params)
    {
        $rules = [
            'school_id' => 'required|numeric',
            'pic'       => 'required|string',
            'pos'       => 'required|numeric',
            'platform'  => 'required|numeric',
            'status'    => 'required|numeric',
        ];

        if (in_array($params['action'], ['del', 'update']))
            $rules['id'] = 'required|numeric';

        $validator = Validator::make($params, $rules);
        if ($validator->fails())
            throw new CdjException($validator->errors()->first(), 40001);

        if ($this->action != 'add' && isset($params['id']) && $params['id']) {
            $info = Advertisments::where('id', $params['id'])->first();
            if (!$info)
                throw new CdjException('广告信息不存在', 40002);
        }

        if ($this->action == 'add') {
            $whereArr = [['school_id', '=', "{$params['school_id']}"], ['pos', '=', "{$params['pos']}"], ['platform', '=', "{$params['platform']}"]];
            $info     = Advertisments::where($whereArr)->first();
            if ($info)
                throw new CdjException('广告已存在', 40002);
        }

        $unixTime          = time();
        $this->operateData = [
            'id'         => ($this->action != 'add' && $params['id']) ? $params['id'] : 0,
            'remark'     => $params['remark'] ?? '',
            'status'     => $params['status'] ?? '',
            'school_id'  => $params['school_id'],
            'pic'        => $params['pic'],
            'pos'        => $params['pos'],
            'platform'   => $params['platform'],
            'updated_at' => $unixTime,
        ];

        if ($this->action == 'add')
            $this->operateData['created_at'] = $unixTime;

        return $this->operateData;
    }

    private function storageData()
    {
        // 开启事务
        DB::beginTransaction();
        try {
            // 数据入库
            switch ($this->action) {
                case 'update':
                    $info = Advertisments::where('id', $this->operateData['id'])->first();
                    Advertisments::where('id', $this->operateData['id'])->update($this->operateData);
                    break;
                case 'add':
                    $info = Advertisments::create($this->operateData);
                    break;
                default:
                    break;
            }
            $this->operateData['id'] = $info->id;

            // 添加操作日志
            $opType = ['add' => 1, 'update' => 2, 'del' => 3];
            if (method_exists($this->advertismentModel, 'addLog')) {
                $this->advertismentModel->addLog($info, [], $opType[$this->action]);
            }

            DB::commit();
        } catch (\Exception $exception) {
            DB::rollBack();
            throw new CdjException($exception->getMessage(), $exception->getCode());
        }

        return true;
    }
}
